import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

public class ABAQuestion {

    private static AtomicInteger atomicInt = new AtomicInteger(100);
    private static AtomicStampedReference<Integer> atomicStampedRef =
            new AtomicStampedReference<Integer>(100,0);

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                atomicInt.compareAndSet(100,101);
                atomicInt.compareAndSet(101,100);
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean res = atomicInt.compareAndSet(100,101);
                System.out.println("thead2: " + res);
            }
        });

        thread2.start();
        thread1.start();
        thread1.join();
        thread2.join();

        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                atomicStampedRef.compareAndSet(100,101,
                        atomicStampedRef.getStamp(),atomicStampedRef.getStamp()+1);
                atomicStampedRef.compareAndSet(100,101,
                        atomicStampedRef.getStamp(),atomicStampedRef.getStamp()+1);

            }
        });
        Thread thread4 = new Thread(new Runnable() {
            @Override
            public void run() {
                int stamp = atomicStampedRef.getStamp();
                System.out.println("stamp: " + stamp);
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean res = atomicStampedRef.compareAndSet(100,101,stamp,stamp+1);
                System.out.println("Thread4: "  + res);
                System.out.println("stamp: " + atomicStampedRef.getStamp());
            }
        });
        thread3.start();
        thread4.start();
    }
}
